Control Flow in GoloScript
This comprehensive guide explains how to use control flow structures in GoloScript: conditionals, loops, and the match operator.
Introduction
GoloScript provides modern and expressive control flow structures that enable you to write clear and elegant code. All control structures are expressions that return values.
✨ What’s New: GoloScript now supports else if for more readable conditional chains!
Conditionals (if-else)
Basic If
let age = 18
if age >= 18 {
println("You are an adult")
}
If-else
if age >= 18 {
println("You are an adult")
} else {
println("You are a minor")
}
Functions with Conditionals
function max = |a, b| {
if a > b {
return a
} else {
return b
}
}
println(max(10, 20)) # 20
Else If
GoloScript now supports else if chains for more readable multiple conditions.
Syntax
if condition1 {
# Code if condition1 is true
} else if condition2 {
# Code if condition2 is true
} else if condition3 {
# Code if condition3 is true
} else {
# Code if no condition is true
}
Example: Grade Calculator
function getGrade = |score| {
if score >= 90 {
return "A (Excellent)"
} else if score >= 80 {
return "B (Good)"
} else if score >= 70 {
return "C (Average)"
} else if score >= 60 {
return "D (Pass)"
} else {
return "F (Fail)"
}
}
println(getGrade(85)) # B (Good)
Example: Age Categories
function describeAge = |age| {
if age < 0 {
return "Invalid age"
} else if age < 2 {
return "Baby"
} else if age < 13 {
return "Child"
} else if age < 20 {
return "Teenager"
} else if age < 65 {
return "Adult"
} else {
return "Senior"
}
}
Loops
GoloScript offers several loop types for different needs.
While
var counter = 1
while counter <= 5 {
println("Count:", counter)
counter = counter + 1
}
For
Classic for loop with initialization, condition, and increment:
for (var i = 1, i <= 5, i = i + 1) {
println("i =", i)
}
Counting backwards:
for (var j = 10, j >= 1, j = j - 1) {
print(j + " ")
}
println("Blastoff! 🚀")
Foreach
Iterate over collections:
let fruits = list["apple", "banana", "cherry"]
foreach fruit in fruits {
println("- " + fruit)
}
With numbers:
let numbers = list[10, 20, 30, 40, 50]
var sum = 0
foreach n in numbers {
sum = sum + n
}
println("Sum:", sum) # 150
Ranges
Use ranges with foreach:
# Inclusive range [1..5]
foreach n in [1..5] {
println(n) # Prints 1, 2, 3, 4, 5
}
Calculate a sum:
var total = 0
foreach i in [1..10] {
total = total + i
}
println("Sum of 1 to 10:", total) # 55
Functions with Loops
function factorial = |n| {
var result = 1
var i = 1
while i <= n {
result = result * i
i = i + 1
}
return result
}
println("5! =", factorial(5)) # 120
The Match Operator
The match operator is an elegant alternative to if-else chains. It’s the recommended approach for multiple conditions.
Basic Syntax
function classify = |n| {
return match {
when n < 0 then "negative"
when n == 0 then "zero"
when n > 0 then "positive"
otherwise "unknown"
}
}
With Complex Conditions
function describeNumber = |n| {
return match {
when n < 0 then "negative"
when n == 0 then "zero"
when n > 0 and n < 10 then "small positive"
when n >= 10 and n < 100 then "medium positive"
otherwise "large positive"
}
}
Match for Grades
function calculateGrade = |score| {
return match {
when score >= 90 then "A (Excellent)"
when score >= 80 then "B (Good)"
when score >= 70 then "C (Average)"
when score >= 60 then "D (Pass)"
otherwise "F (Fail)"
}
}
Inline Match
let temp = 25
println("Temperature:", temp + "°C")
println("Feeling:", match {
when temp < 0 then "freezing 🥶"
when temp < 10 then "cold ❄️"
when temp < 20 then "cool 🌤️"
when temp < 30 then "comfortable ☀️"
otherwise "hot 🔥"
})
Match Without Otherwise
If no condition matches, match returns null:
let value = 100
let result = match {
when value < 50 then "small"
when value < 75 then "medium"
}
if result == null {
println("No match found")
}
FizzBuzz with Match
function fizzbuzz = |n| {
return match {
when n % 15 == 0 then "FizzBuzz"
when n % 3 == 0 then "Fizz"
when n % 5 == 0 then "Buzz"
otherwise n
}
}
for (var i = 1, i <= 15, i = i + 1) {
print(fizzbuzz(i) + " ")
}
# Output: 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
Comparing Approaches
Approach 1: Nested If
function getDayType1 = |day| {
if day >= 1 and day <= 5 {
return "Weekday"
} else {
if day == 6 or day == 7 {
return "Weekend"
} else {
return "Invalid"
}
}
}
Pros: Traditional, familiar Cons: Verbose, hard to read with many conditions
Approach 2: Else If (✨ New!)
function getDayType2 = |day| {
if day >= 1 and day <= 5 {
return "Weekday"
} else if day == 6 or day == 7 {
return "Weekend"
} else {
return "Invalid"
}
}
Pros: Readable, flat, familiar to most languages Cons: Still somewhat verbose
Approach 3: Match (⭐ Recommended!)
function getDayType3 = |day| {
return match {
when day >= 1 and day <= 5 then "Weekday"
when day == 6 or day == 7 then "Weekend"
otherwise "Invalid"
}
}
Pros: Concise, expressive, idiomatic GoloScript, returns value directly Cons: Less familiar syntax for some
When to Use What?
| Situation | Recommendation |
|---|---|
| 1-2 simple conditions | Simple if-else |
| 3+ conditions | match (recommended) or else if |
| Pattern matching | match only |
| Existing code with if-else | else if for transition |
| New code | Prefer match |
Practical Examples
Example 1: Voting System
function canVote = |age| {
if age >= 18 {
return true
} else {
return false
}
}
function getVotingStatus = |age| {
return match {
when age < 0 then "Invalid age"
when age < 18 then "Too young to vote (" + (18 - age) + " years to wait)"
when age >= 18 and age < 65 then "Can vote"
otherwise "Can vote (senior)"
}
}
Example 2: Ticket Pricing
function getTicketPrice = |age| {
if age < 12 {
return 5.0
} else if age >= 65 {
return 7.0
} else {
return 10.0
}
}
# Or with match (more elegant):
function getTicketPriceMatch = |age| {
return match {
when age < 12 then 5.0
when age >= 65 then 7.0
otherwise 10.0
}
}
Example 3: Leap Year
function isLeapYear = |year| {
if year % 400 == 0 {
return true
} else if year % 100 == 0 {
return false
} else if year % 4 == 0 {
return true
} else {
return false
}
}
# Or with match:
function isLeapYearMatch = |year| {
return match {
when year % 400 == 0 then true
when year % 100 == 0 then false
when year % 4 == 0 then true
otherwise false
}
}
Example 4: Nested Loops - Multiplication Table
for (var row = 1, row <= 5, row = row + 1) {
for (var col = 1, col <= 5, col = col + 1) {
let product = row * col
print(product + " ")
}
println()
}
Example 5: Complete FizzBuzz
function fizzBuzz = |limit| {
for (var n = 1, n <= limit, n = n + 1) {
let result = match {
when n % 15 == 0 then "FizzBuzz"
when n % 3 == 0 then "Fizz"
when n % 5 == 0 then "Buzz"
otherwise n
}
println(result)
}
}
fizzBuzz(20)
Logical Operators
AND
if score >= 70 and attendance >= 80 {
println("Pass with good attendance")
}
OR
if isWeekend or isHoliday {
println("No work today!")
}
NOT
if not isRaining {
println("You can go outside!")
}
Combinations
if (grade >= 80 and effort >= 90) or grade >= 95 {
println("Excellent performance!")
}
Comparison Operators
| Operator | Description | Example |
|---|---|---|
== |
Equal | x == y |
!= |
Not equal | x != y |
< |
Less than | x < y |
<= |
Less than or equal | x <= y |
> |
Greater than | x > y |
>= |
Greater than or equal | x >= y |
is |
Identity | x is y |
isnt |
Not identity | x isnt y |
Summary
Control flow structures in GoloScript are:
- Expressive:
if,else if,else,match,while,for,foreach - Flexible: Multiple approaches for the same problem
- Modern:
matchfor pattern matching,else iffor readability - Powerful: Combination of all structures for complex patterns
General Recommendation: Use match for multiple conditions (more idiomatic), else if for transitioning from other languages, and simple if-else for basic cases.